/*
 * $Id$ 
 */
package com.representqueens.spark;

import java.awt.Color;

import com.representqueens.spark.util.StringConversion;

/*
 * Copyright 2011 Rob Whelan for Patients Know Best
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Possible bits of data associated with a datapoint in a graph. All are
 * optional except the y value.
 * 
 * @author Rob Whelan <rob@patientsknowbest.com>
 * @version $Revision$ $Date$
 */
public class DataPoint {

	public enum Shape {
		CIRCLE("circ");

		private final String value;

		Shape(String v) {
			this.value = v;
		}

		public String toString() {
			return value;
		}

		public static Shape fromValue(String v) {
			for (Shape s : Shape.values()) {
				if (s.value.equals(v)) {
					return s;
				}
			}
			throw new IllegalArgumentException(v.toString());
		}
	}

	private Double y;
	private Double x;
	private Double rangeLow;
	private Double rangeHigh;
	private Shape shape; // currently, only circle is supported (pins on line graphs)
	private Color color; // the color of the shape

	public DataPoint(Double y) {
		this.y = y;
	}
	
	public DataPoint(String spec) {
		String[] paramArr = spec.split(":");
		setY(Double.parseDouble(paramArr[0]));
		for (int i = 1; i < paramArr.length; i++) {
			String param = paramArr[i];
			if (param.startsWith("x")) {
				setX(Double.parseDouble(param.substring("x".length())));
			} else if (param.startsWith("lo")) {
				setRangeLow(Double.parseDouble(param.substring("lo".length())));
			} else if (param.startsWith("hi")) {
				setRangeHigh(Double.parseDouble(param.substring("hi".length())));
			} else if (param.startsWith("sh")) {
				setShape(Shape.fromValue(param.substring("sh".length())));
			} else if (param.startsWith("co")) {
				setColor(StringConversion.convertColor(
						param.substring("co".length()), Color.RED));
			}
		}

		// possible validations:
		// x values must be positive
		// both range values must be set, or neither
		// range high must be above range low
	}

	public String toString() {
		String s = Double.toString(y);
		if (x != null)
			s += ":x" + x;
		if (rangeLow != null)
			s += ":lo" + rangeLow;
		if (rangeHigh != null)
			s += ":hi" + rangeHigh;
		if (shape != null)
			s += ":sh" + shape;
		if (color != null)
			// strip alpha bits and make sure we have leading 0's
			s += ":co" + Integer.toHexString((color.getRGB() & 0xffffff) | 0x1000000).substring(1);

		return s;
	}
	
	public boolean hasRange() {
		return getRangeHigh() != null;
	}
	
	public boolean hasShape() {
		return getShape() != null;
	}

	public Double getY() {
		return y;
	}

	public void setY(Double y) {
		this.y = y;
	}

	public Double getX() {
		return x;
	}

	public void setX(Double x) {
		this.x = x;
	}

	public Double getRangeLow() {
		return rangeLow;
	}

	public void setRangeLow(Double rangeLow) {
		this.rangeLow = rangeLow;
	}

	public Double getRangeHigh() {
		return rangeHigh;
	}

	public void setRangeHigh(Double rangeHigh) {
		this.rangeHigh = rangeHigh;
	}

	public Shape getShape() {
		return shape;
	}

	public void setShape(Shape shape) {
		this.shape = shape;
	}

	public Color getColor() {
		return color;
	}

	public void setColor(Color color) {
		this.color = color;
	}
}
